﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Excel = Microsoft.Office.Interop.Excel;
using System.Diagnostics;
using DimensionData.Data2;
using DimensionAddIn.Render;
using System.Text.RegularExpressions;
using DimensionData;

namespace DimensionAddIn
{
    public class DocRender
    {
        public Excel.Worksheet _worksheet;

        private Dictionary<int, MergeInfo> _yMergeDict;
        private Dictionary<int, MergeInfo> _xMergeDict;

        public DocRender(Excel.Worksheet worksheet)
        {
            _worksheet = worksheet;
        }

        public void RenderContent(DocDimData schema, DocData docMatrix)
        {
            _worksheet = Globals.ThisAddIn.Application.ActiveSheet;

            _yMergeDict = new Dictionary<int, MergeInfo>();
            _xMergeDict = new Dictionary<int, MergeInfo>();

            DTree yTree = schema.YTree;
            DTree xTree = schema.XTree;
            List<PageDim> pageDims = schema.PageDims;

            int beginRow = 5;
            int firstRow = 5;
            int beginCol = 2;
            int firstCol = 2;

            int ydCount = yTree.Table.RelationChain.Relations.Count + 1;
            int yvdCount = GetVisibleYDimCount(schema);
            int xdCount = xTree.Table.RelationChain.Relations.Count + 1;
            // 总的需要显示的x维度表数量
            int xvdCount = GetVisibleXDimCount(schema);

            firstCol += yvdCount;
            firstRow += xvdCount;

            List<DRow> yRows = yTree.Complanate2();
            List<DRow> xRows = xTree.Complanate2();

            // 当前可见的y维度行的行号索引列表
            List<int> visualYRows = new List<int>();
            // 当前可见的x维度行的行号索引列表
            List<int> visualXRows = new List<int>();

            #region 清除当前内容区域
            if (docMatrix.VisualRect.IsValid())
            {
                Debug.WriteLine("clear rect:{0},{1}-{2},{3}",
                    docMatrix.VisualRect.BeginRow,
                    docMatrix.VisualRect.BeginCol,
                    docMatrix.VisualRect.EndRow,
                    docMatrix.VisualRect.EndCol);
                Excel.Range ltCell = _worksheet.XGetCell(docMatrix.VisualRect.BeginRow, docMatrix.VisualRect.BeginCol);
                Excel.Range rbCell = _worksheet.XGetCell(docMatrix.VisualRect.EndRow, docMatrix.VisualRect.EndCol);
                _worksheet.Range[ltCell, rbCell].Clear();
            }
            #endregion

            #region 渲染表头
            // 表头显示的行维的名称
            int headerIndex = 0;
            for (int index = 0; index < yTree.Table.Tables.Count; index++)
            {
                if (IsYDimVisible(yTree.Table.Tables[index].Code, schema))
                {
                    Excel.Range rowTitleRange = _worksheet.XGetCell(beginRow, beginCol + headerIndex);
                    rowTitleRange.Value2 = yTree.Table.Tables[index].Name;
                    Excel.Range mergeRange = _worksheet.XGetRange(
                        beginRow,
                        beginCol + headerIndex,
                        beginRow + xvdCount - 1,
                        beginCol + headerIndex);
                    mergeRange.Merge(rowTitleRange.MergeCells);

                    mergeRange.Interior.Color = 0xffcf9c;
                    mergeRange.Borders[Excel.XlBordersIndex.xlEdgeLeft].Weight = Excel.XlBorderWeight.xlThin;
                    mergeRange.Borders[Excel.XlBordersIndex.xlEdgeTop].Weight = Excel.XlBorderWeight.xlThin;
                    mergeRange.Borders[Excel.XlBordersIndex.xlEdgeRight].Weight = Excel.XlBorderWeight.xlThin;
                    mergeRange.Borders[Excel.XlBordersIndex.xlEdgeBottom].Weight = Excel.XlBorderWeight.xlThin;
                    mergeRange.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;
                    headerIndex++;
                }
            }
            #endregion

            #region 渲染y维度
            int aRowIndex = 0;
            for (int rowIndex = 0; rowIndex < yRows.Count; rowIndex++)
            {
                DRow dtRow = yRows[rowIndex];

                bool isVisible = true;
                #region 判断此行是否被页面维度过滤
                foreach (var pageDim in pageDims)
                {
                    if (pageDim.SelectedNames.Count>0 && pageDim.Direction == DimensionData.DimDirection.Y)
                    {
                        string cpdName = dtRow.Items[pageDim.Index].Name;
                        if (!pageDim.SelectedNames.Contains(cpdName))
                        {
                            isVisible = false;
                            break;
                        }
                    }
                }
                #endregion

                if (isVisible)
                {
                    // 在显示的维度行记录中，添加当前维度行号
                    visualYRows.Add(rowIndex);

                    // 行维的维度名称实际的渲染列索引
                    int dActualIndex = 0;
                    for (int dIndex = 0; dIndex < ydCount; dIndex++)
                    {
                        string codePath = dtRow.GetCodePath(dIndex);
                        DItem dItem = dtRow.Items[dIndex];

                        // 判断维度表是否需要显示
                        if (!IsYDimVisible(dIndex, schema))
                        {
                            continue;
                        }

                        MergeInfo mergeInfo = null;
                        bool isRepeat = false;
                        if (_yMergeDict.ContainsKey(dIndex))
                        {
                            MergeInfo existMerge = _yMergeDict[dIndex];
                            if (existMerge.CodePath == codePath)
                            {
                                existMerge.RepeatCount++;
                                isRepeat = true;
                            }
                            else
                            {
                                mergeInfo = existMerge;

                                MergeInfo newMergeInfo = new MergeInfo();
                                newMergeInfo.BeginCell = _worksheet.XGetCell(firstRow + aRowIndex, beginCol + dActualIndex);
                                newMergeInfo.RepeatCount = 0;
                                newMergeInfo.CodePath = codePath;
                                _yMergeDict[dIndex] = newMergeInfo;
                            }
                        }
                        else
                        {
                            mergeInfo = new MergeInfo();
                            mergeInfo.BeginCell = _worksheet.XGetCell(firstRow + aRowIndex, beginCol + dActualIndex);
                            mergeInfo.RepeatCount = 0;
                            mergeInfo.CodePath = codePath;
                            _yMergeDict.Add(dIndex, mergeInfo);
                        }

                        if (mergeInfo != null && mergeInfo.RepeatCount > 0)
                        {
                            Excel.Range mergeRange = _worksheet.XGetRange(
                                mergeInfo.BeginCell.Row,
                                mergeInfo.BeginCell.Column,
                                mergeInfo.BeginCell.Row + mergeInfo.RepeatCount,
                                mergeInfo.BeginCell.Column);
                            _worksheet.XGetRange(
                                mergeInfo.BeginCell.Row, 
                                mergeInfo.BeginCell.Column,
                                mergeInfo.BeginCell.Row + mergeInfo.RepeatCount,
                                mergeInfo.BeginCell.Column).Merge(mergeInfo.BeginCell.MergeCells);


                            mergeRange.Interior.Color = 0xffcf9c;
                            mergeRange.Borders[Excel.XlBordersIndex.xlEdgeLeft].Weight = Excel.XlBorderWeight.xlThin;
                            mergeRange.Borders[Excel.XlBordersIndex.xlEdgeTop].Weight = Excel.XlBorderWeight.xlThin;
                            mergeRange.Borders[Excel.XlBordersIndex.xlEdgeRight].Weight = Excel.XlBorderWeight.xlThin;
                            mergeRange.Borders[Excel.XlBordersIndex.xlEdgeBottom].Weight = Excel.XlBorderWeight.xlThin;
                        }

                        if (!isRepeat)
                        {
                            // 重复出现的维度名称，不在创建到excel上
                            Excel.Range range = _worksheet.XGetCell(firstRow + aRowIndex, beginCol + dActualIndex);
                            range.Value2 = dtRow.Items[dIndex].Name;
                            range.IndentLevel = dtRow.Items[dIndex].Level;
                            range.Interior.Color = 0xffcf9c;
                            range.Borders[Excel.XlBordersIndex.xlEdgeLeft].Weight = Excel.XlBorderWeight.xlThin;
                            range.Borders[Excel.XlBordersIndex.xlEdgeTop].Weight = Excel.XlBorderWeight.xlThin;
                            range.Borders[Excel.XlBordersIndex.xlEdgeRight].Weight = Excel.XlBorderWeight.xlThin;
                            range.Borders[Excel.XlBordersIndex.xlEdgeBottom].Weight = Excel.XlBorderWeight.xlThin;
                        }
                        dActualIndex++;
                    }
                    aRowIndex++;
                }
            }

            #region 检查最后的单元格
            foreach (var ymergeKey in _yMergeDict.Keys)
            {
                MergeInfo mergeInfo = _yMergeDict[ymergeKey];
                Excel.Range mergeRange = _worksheet.XGetRange(mergeInfo.BeginCell.Row, mergeInfo.BeginCell.Column,
                    mergeInfo.BeginCell.Row + mergeInfo.RepeatCount,
                    mergeInfo.BeginCell.Column);
                _worksheet.XGetRange(mergeInfo.BeginCell.Row, mergeInfo.BeginCell.Column,
                    mergeInfo.BeginCell.Row + mergeInfo.RepeatCount,
                    mergeInfo.BeginCell.Column).Merge(mergeInfo.BeginCell.MergeCells);


                mergeRange.Interior.Color = 0xffcf9c;
                mergeRange.Borders[Excel.XlBordersIndex.xlEdgeLeft].Weight = Excel.XlBorderWeight.xlThin;
                mergeRange.Borders[Excel.XlBordersIndex.xlEdgeTop].Weight = Excel.XlBorderWeight.xlThin;
                mergeRange.Borders[Excel.XlBordersIndex.xlEdgeRight].Weight = Excel.XlBorderWeight.xlThin;
                mergeRange.Borders[Excel.XlBordersIndex.xlEdgeBottom].Weight = Excel.XlBorderWeight.xlThin;
            }
            #endregion
            #endregion

            #region 渲染x维度
            int aColIndex = 0;
            for (int rowIndex = 0; rowIndex < xRows.Count; rowIndex++)
            {
                DRow dtRow = xRows[rowIndex];

                bool isVisible = true;
                #region 判断是否被页面维过滤
                foreach (var pageDim in pageDims)
                {
                    if (pageDim.Direction == DimensionData.DimDirection.X && pageDim.SelectedNames.Count>0)
                    {
                        string cpdName = dtRow.Items[pageDim.Index].Name;
                        if (!pageDim.SelectedNames.Contains(cpdName))
                        {
                            isVisible = false;
                            break;
                        }
                    }
                }
                #endregion

                if (isVisible)
                {
                    visualXRows.Add(rowIndex);

                    // 实际的列维渲染行索引
                    int dActualIndex = 0;
                    for (int dIndex = 0; dIndex < xdCount; dIndex++)
                    {
                        string codePath = dtRow.GetCodePath(dIndex);
                        DItem dItem = dtRow.Items[dIndex];

                        MergeInfo mergeInfo = null;
                        bool isRepeat = false;
                        if (_xMergeDict.ContainsKey(dIndex))
                        {
                            MergeInfo existMerge = _xMergeDict[dIndex];
                            if (existMerge.CodePath == codePath)
                            {
                                existMerge.RepeatCount++;
                                isRepeat = true;
                            }
                            else
                            {
                                mergeInfo = existMerge;

                                MergeInfo newMergeInfo = new MergeInfo();
                                newMergeInfo.BeginCell = _worksheet.XGetCell(beginRow + dActualIndex, firstCol + aColIndex);
                                newMergeInfo.RepeatCount = 0;
                                newMergeInfo.CodePath = codePath;
                                _xMergeDict[dIndex] = newMergeInfo;
                            }
                        }
                        else
                        {
                            mergeInfo = new MergeInfo();
                            mergeInfo.BeginCell = _worksheet.XGetCell(beginRow + dActualIndex, firstCol + aColIndex);
                            mergeInfo.RepeatCount = 0;
                            mergeInfo.CodePath = codePath;
                            _xMergeDict.Add(dIndex, mergeInfo);
                        }

                        if (mergeInfo != null && mergeInfo.RepeatCount > 0)
                        {
                            Excel.Range mergeRange = _worksheet.XGetRange(mergeInfo.BeginCell.Row, mergeInfo.BeginCell.Column,
                                mergeInfo.BeginCell.Row,
                                mergeInfo.BeginCell.Column + mergeInfo.RepeatCount);
                            _worksheet.XGetRange(mergeInfo.BeginCell.Row, mergeInfo.BeginCell.Column,
                                mergeInfo.BeginCell.Row,
                                mergeInfo.BeginCell.Column + mergeInfo.RepeatCount).Merge(mergeInfo.BeginCell.MergeCells);


                            mergeRange.Interior.Color = 0xffcf9c;
                            mergeRange.Borders[Excel.XlBordersIndex.xlEdgeLeft].Weight = Excel.XlBorderWeight.xlThin;
                            mergeRange.Borders[Excel.XlBordersIndex.xlEdgeTop].Weight = Excel.XlBorderWeight.xlThin;
                            mergeRange.Borders[Excel.XlBordersIndex.xlEdgeRight].Weight = Excel.XlBorderWeight.xlThin;
                            mergeRange.Borders[Excel.XlBordersIndex.xlEdgeBottom].Weight = Excel.XlBorderWeight.xlThin;
                            mergeRange.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;
                        }

                        if (!isRepeat)
                        {
                            // 重复出现的维度名称，不在创建到excel上
                            Excel.Range range = _worksheet.XGetCell(beginRow + dActualIndex, firstCol + aColIndex);
                            range.Value2 = dItem.Name;
                            range.Interior.Color = 0xffcf9c;
                            range.Borders[Excel.XlBordersIndex.xlEdgeLeft].Weight = Excel.XlBorderWeight.xlThin;
                            range.Borders[Excel.XlBordersIndex.xlEdgeTop].Weight = Excel.XlBorderWeight.xlThin;
                            range.Borders[Excel.XlBordersIndex.xlEdgeRight].Weight = Excel.XlBorderWeight.xlThin;
                            range.Borders[Excel.XlBordersIndex.xlEdgeBottom].Weight = Excel.XlBorderWeight.xlThin;
                            range.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;
                        }
                        dActualIndex++;
                    }
                    aColIndex++;
                }
            }

            #region 检查最后的单元格
            foreach (var xmergeKey in _xMergeDict.Keys)
            {
                MergeInfo mergeInfo = _xMergeDict[xmergeKey];
                if (mergeInfo.RepeatCount > 0)
                {
                    Excel.Range mergeRange = _worksheet.XGetRange(mergeInfo.BeginCell.Row, mergeInfo.BeginCell.Column,
                        mergeInfo.BeginCell.Row, mergeInfo.BeginCell.Column + mergeInfo.RepeatCount);
                    _worksheet.XGetRange(mergeInfo.BeginCell.Row, mergeInfo.BeginCell.Column,
                        mergeInfo.BeginCell.Row, mergeInfo.BeginCell.Column + mergeInfo.RepeatCount).Merge(mergeInfo.BeginCell.MergeCells);
                    
                    mergeRange.Interior.Color = 0xffcf9c;
                    mergeRange.Borders[Excel.XlBordersIndex.xlEdgeLeft].Weight = Excel.XlBorderWeight.xlThin;
                    mergeRange.Borders[Excel.XlBordersIndex.xlEdgeTop].Weight = Excel.XlBorderWeight.xlThin;
                    mergeRange.Borders[Excel.XlBordersIndex.xlEdgeRight].Weight = Excel.XlBorderWeight.xlThin;
                    mergeRange.Borders[Excel.XlBordersIndex.xlEdgeBottom].Weight = Excel.XlBorderWeight.xlThin;
                    mergeRange.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;
                }
            }
            #endregion
            #endregion

            #region 更新内容区域
            docMatrix.VisualRect.BeginRow = beginRow;
            docMatrix.VisualRect.EndRow = (beginRow + visualYRows.Count + xdCount);
            docMatrix.VisualRect.BeginCol = beginCol;
            docMatrix.VisualRect.EndCol = (beginCol + visualXRows.Count + ydCount);
            Debug.WriteLine("set rect:{0},{1}-{2},{3}",
                docMatrix.VisualRect.BeginRow,
                docMatrix.VisualRect.BeginCol,
                docMatrix.VisualRect.EndRow,
                docMatrix.VisualRect.EndCol);
            #endregion

            docMatrix.VisualRect.YRowIndexList = visualYRows;
            docMatrix.VisualRect.XRowIndexList = visualXRows;

            docMatrix.VisualRect.DataBeginRow = firstRow;
            docMatrix.VisualRect.DataBeginCol = firstCol;
            docMatrix.VisualRect.DataEndRow = docMatrix.VisualRect.DataBeginRow + docMatrix.VisualRect.YRowIndexList.Count;
            docMatrix.VisualRect.DataEndCol = docMatrix.VisualRect.DataBeginCol + docMatrix.VisualRect.XRowIndexList.Count;

            RenderCalcModel(schema, docMatrix);

            try
            {
                LoadData(schema, docMatrix);

                LoadRefData(docMatrix);
            }
            catch
            {
            }

            RenderData(schema, docMatrix);
        }

        /// <summary>
        /// 渲染计算模型
        /// </summary>
        /// <param name="dimData"></param>
        /// <param name="docData"></param>
        protected void RenderCalcModel(DocDimData dimData, DocData docData)
        {
            List<DRow> yRows = dimData.YTree.Complanate2();
            List<DRow> xRows = dimData.XTree.Complanate2();

            for (int yIndex = 0; yIndex < docData.VisualRect.YRowIndexList.Count; yIndex++)
            {
                for (int xIndex = 0; xIndex < docData.VisualRect.XRowIndexList.Count; xIndex++)
                {
                    DRow yRow = yRows[docData.VisualRect.YRowIndexList[yIndex]];
                    DRow xRow = xRows[docData.VisualRect.XRowIndexList[xIndex]];

                    DRow fullRow = yRow.Connect(xRow);

                    DataRef dataRef = fullRow.GetDataRef(dimData.RRules);
                    if (dataRef != null)
                    {
                        string codePath = fullRow.GetCodePath();
                        PathExpression varPath = new PathExpression(codePath).Locate(dataRef.SourceExp);
                        Debug.WriteLine(string.Format("需要引用数据:doc({0}) path({1})", dataRef.SourceDocCode, varPath.ToPathString()));
                        docData.DataRefList.Add(new DataRefItem() { Path = codePath, SourceDocType = dataRef.SourceDocCode, SourcePath = varPath.ToPathString() });
                        Excel.Range cell = _worksheet.XGetCell(docData.VisualRect.DataBeginRow + yIndex, docData.VisualRect.DataBeginCol + xIndex);
                        RenderDataRef(cell, dataRef);
                    }
                    else
                    {
                        FormulaRef formula = fullRow.GetFormula(dimData.FRules);
                        if (formula != null)
                        {
                            // 存在计算公式
                            string codePath = fullRow.GetCodePath();
                            string[] codePathSegements = codePath.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);
                            Debug.WriteLine(string.Format("{0}存在公式{1}", codePath, formula.Value));

                            Regex regex = new Regex(@"#(?<code>[^#]*)#");
                            MatchCollection matchs = regex.Matches(formula.Value);

                            string resolvedFormula = formula.Value;

                            // 生成公式错误
                            // 1.可能是在页面维度上选择了合计维度，导致明细维度不显示，无法生成计算公式
                            // 2.发生这种情况的时候，我们将单元格标记为公式单元格的样式，但是不生成公式，直接把值写入到excel上
                            // 3.不允许用户修改
                            bool buildFormulaError = false;

                            foreach (Match match in matchs)
                            {
                                PathExpression varPath = new PathExpression(codePath).Locate(new PathExpression(match.Groups["code"].Value));

                                // 需要将codepath转换为单元格位置
                                ExcelPos varPos = docData.GetXlsPos(varPath.ToPathString());
                                if (varPos == null)
                                {
                                    buildFormulaError = true;
                                    break;
                                }
                                else
                                {
                                    resolvedFormula = resolvedFormula.Replace(match.Value, varPos.ToXlsString());
                                }
                            }
                            if (!buildFormulaError)
                            {
                                // 设置公式
                                _worksheet.XGetCell(docData.VisualRect.DataBeginRow + yIndex, docData.VisualRect.DataBeginCol + xIndex).Formula = "=" + resolvedFormula;
                            }
                            else
                            {
                            }
                            _worksheet.XGetCell(docData.VisualRect.DataBeginRow + yIndex, docData.VisualRect.DataBeginCol + xIndex).Interior.Color = 0xceffce;
                            _worksheet.XGetCell(docData.VisualRect.DataBeginRow + yIndex, docData.VisualRect.DataBeginCol + xIndex).Borders[Excel.XlBordersIndex.xlEdgeRight].LineStyle = Excel.XlLineStyle.xlDash;
                            _worksheet.XGetCell(docData.VisualRect.DataBeginRow + yIndex, docData.VisualRect.DataBeginCol + xIndex).Borders[Excel.XlBordersIndex.xlEdgeBottom].LineStyle = Excel.XlLineStyle.xlDash;
                        }
                        else
                        {
                            ///* 不设置样式
                            _worksheet.XGetCell(docData.VisualRect.DataBeginRow + yIndex, docData.VisualRect.DataBeginCol + xIndex).Borders[Excel.XlBordersIndex.xlEdgeRight].LineStyle = Excel.XlLineStyle.xlDash;
                            _worksheet.XGetCell(docData.VisualRect.DataBeginRow + yIndex, docData.VisualRect.DataBeginCol + xIndex).Borders[Excel.XlBordersIndex.xlEdgeBottom].LineStyle = Excel.XlLineStyle.xlDash;
                            //*/ 
                        }
                    }
                }
            }
        }

        protected void LoadData(DocDimData dimData, DocData docData)
        {
            DServ.DExcelServiceClient client = ThisAddIn.CreateClient();
            string values = client.GetDatas(
                            new Guid("{4DD16CEF-3906-4263-B506-4D90E9CAE34C}"),
                            new Guid("{15787EE0-BD4B-4A21-B79D-90698C24EE5C}"),
                            dimData.DocType);
            string[] segements = values.Split(new char[] { ',' });
            int count = segements.Length / 2;
            for (int index = 0; index < count; index++)
            {
                string path = segements[2 * index];
                string value = segements[2 * index + 1];

                if (!string.IsNullOrEmpty(value))
                {
                    docData.ValueTable.SetValue(path, value);
                }
            }
        }

        /// <summary>
        /// 加载引用的数据
        /// </summary>
        /// <param name="docData"></param>
        protected void LoadRefData(DocData docData)
        {
            if (docData.DataRefList.Count > 0)
            {
                DServ.DExcelServiceClient client = ThisAddIn.CreateClient();
                foreach (var item in docData.DataRefList)
                {
                    item.Value = client.GetData(
                            new Guid("{4DD16CEF-3906-4263-B506-4D90E9CAE34C}"),
                            new Guid("{15787EE0-BD4B-4A21-B79D-90698C24EE5C}"),
                            item.SourceDocType,
                            item.SourcePath);

                    docData.ValueTable.SetValue(item.Path, item.Value);
                }

                // 将
            }
        }

        protected void RenderData(DocDimData docSchema, DocData docMatrix)
        {
            List<DRow> yRows = docSchema.YTree.Complanate2();
            List<DRow> xRows = docSchema.XTree.Complanate2();

            for (int yIndex = 0; yIndex < docMatrix.VisualRect.YRowIndexList.Count; yIndex++)
            {
                DRow yRow = yRows[docMatrix.VisualRect.YRowIndexList[yIndex]];
                for (int xIndex = 0; xIndex < docMatrix.VisualRect.XRowIndexList.Count; xIndex++)
                {
                    DRow xRow = xRows[docMatrix.VisualRect.XRowIndexList[xIndex]];
                    StringBuilder builder = new StringBuilder();
                    builder.AppendFormat("{0}{1}", yRow.GetCodePath(), xRow.GetCodePath());
                    Excel.Range range = _worksheet.XGetCell(docMatrix.VisualRect.DataBeginRow + yIndex, docMatrix.VisualRect.DataBeginCol + xIndex);
                    
                    // 非公式单元格才可输入
                    if ((bool)range.HasFormula == false)
                    {
                        range.Value2 = docMatrix.ValueTable.GetValue(builder.ToString());
                    }
                }
            }
        }

        /// <summary>
        /// 渲染页面维度名称及下拉框
        /// </summary>
        /// <param name="schema"></param>
        /// <param name="docMatrix"></param>
        public void RenderPageDim(DocDimData schema, DocData docMatrix)
        {
            docMatrix.VisualRect.PageDimPos = new List<ExcelPos>();
            for (int index = 0; index < schema.PageDims.Count; index++)
            {
                List<DRow> rows = schema.PageDims[index].DimData.Complanate2();

                Excel.Range labelRange = this._worksheet.XGetCell(3, 2 + 2 * index);
                labelRange.Value2 = schema.PageDims[index].DimData.Table.Name;
                labelRange.Interior.Color = 0xffcf9c;
                labelRange.Borders[Excel.XlBordersIndex.xlEdgeLeft].Weight = Excel.XlBorderWeight.xlThin;
                labelRange.Borders[Excel.XlBordersIndex.xlEdgeTop].Weight = Excel.XlBorderWeight.xlThin;
                labelRange.Borders[Excel.XlBordersIndex.xlEdgeRight].Weight = Excel.XlBorderWeight.xlThin;
                labelRange.Borders[Excel.XlBordersIndex.xlEdgeBottom].Weight = Excel.XlBorderWeight.xlThin;

                int cellRow = 3;
                int cellCol = 2 + 2 * index + 1;
                Excel.Range selection = this._worksheet.XGetCell(cellRow, cellCol);
                selection.Validation.Delete();

                string formula = string.Format("={0}dl!{1}{2}:{3}{4}", this._worksheet.Name, ToAA(index + 1), "1", ToAA(index + 1), rows.Count);
                selection.Validation.Add(
                    Excel.XlDVType.xlValidateList,
                    Excel.XlDVAlertStyle.xlValidAlertStop,
                    Type.Missing,
                    formula,
                    Type.Missing);
                
                // 设置初始值
                selection.Value2 = schema.PageDims[index].SelectedNames.First();

                selection.Borders[Excel.XlBordersIndex.xlEdgeLeft].Weight = Excel.XlBorderWeight.xlThin;
                selection.Borders[Excel.XlBordersIndex.xlEdgeTop].Weight = Excel.XlBorderWeight.xlThin;
                selection.Borders[Excel.XlBordersIndex.xlEdgeRight].Weight = Excel.XlBorderWeight.xlThin;
                selection.Borders[Excel.XlBordersIndex.xlEdgeBottom].Weight = Excel.XlBorderWeight.xlThin;

                ExcelPos pos = new ExcelPos(cellRow, cellCol);
                docMatrix.VisualRect.PageDimPos.Add(pos);
            }
        }

        /// <summary>
        /// 渲染数据引用单元格
        /// </summary>
        /// <param name="cell"></param>
        /// <param name="dataRef"></param>
        private void RenderDataRef(Excel.Range cell, DataRef dataRef)
        {
            cell.Interior.Color = 0x9cffff;
            cell.Borders[Excel.XlBordersIndex.xlEdgeRight].LineStyle = Excel.XlLineStyle.xlDash;
            cell.Borders[Excel.XlBordersIndex.xlEdgeBottom].LineStyle = Excel.XlLineStyle.xlDash;
        }

        public static string ToAA(int value)
        {
            string AA = string.Empty;
            int d = value / 26;
            int remainder = value % 26;

            if (d == 1 && remainder == 0)
            {
                AA = ToA(26) + AA;
                d = 0;
            }
            else
            {
                AA = ToA(remainder) + AA;
            }

            while (d > 0)
            {
                remainder = d % 26;
                d = d / 26;
                AA = ToA(remainder) + AA;
            }
            return AA;
        }

        private static string ToA(int value)
        {
            if (value <= 0)
            {
                return string.Empty;
            }
            return new string((char)('A' + (value - 1)), 1);
        }

        #region 获取可见的维度数量
        public int GetVisibleYDimCount(DocDimData dimData)
        {
            int count = 0;
            foreach (var table in dimData.YTree.Table.Tables)
            {
                bool isVisible = true;
                foreach (var dim in dimData.PageDims)
                {
                    if (dim.DimData.Table.Code == table.Code && !dim.IsVisible)
                    {
                        isVisible = false;
                        break;
                    }
                }
                if (isVisible)
                {
                    count++;
                }
            }
            return count;
        }

        public int GetVisibleXDimCount(DocDimData dimData)
        {
            int count = 0;
            foreach (var table in dimData.XTree.Table.Tables)
            {
                bool isVisible = true;
                foreach (var dim in dimData.PageDims)
                {
                    if (dim.DimData.Table.Code == table.Code && !dim.IsVisible)
                    {
                        isVisible = false;
                        break;
                    }
                }
                if (isVisible)
                {
                    count++;
                }
            }
            return count;
        }
        #endregion
        /// <summary>
        /// 判断此维度表是否显示
        /// </summary>
        /// <param name="dimTableCode"></param>
        /// <param name="dimData"></param>
        /// <returns></returns>
        private bool IsYDimVisible(string dimTableCode, DocDimData dimData)
        {
            foreach (var dim in dimData.PageDims)
            {
                if (dim.DimData.Table.Code == dimTableCode && !dim.IsVisible)
                {
                    return false;
                }
            }
            return true;
        }
        /// <summary>
        /// 判断此维度表是否显示
        /// </summary>
        /// <param name="dimTableCode"></param>
        /// <param name="dimData"></param>
        /// <returns></returns>
        private bool IsYDimVisible(int dimIndex, DocDimData dimData)
        {
            foreach (var dim in dimData.PageDims)
            {
                if (dim.Index == dimIndex && !dim.IsVisible)
                {
                    return false;
                }
            }
            return true;
        }
    }
}
